﻿#include "GY_GraphicsPolyline.h"
#include "Graphics/GY_GraphicsReflection.h"

GY_GraphicsPolyline::GY_GraphicsPolyline(const QString &guid, QGraphicsItem *parent)
    :GY_BasicsGraphicsObject(guid,this,parent)
{
    //图元类型
    GY_Object::setUserData(GY_ENUM::ClassType,QVariant("PolylineItem"));
    initializationPropertyInfo();
//    QVector<QPointF> PtsArray;
    QMap<QVariant,QPointF> editPoints = {
        {"PtsArray[0]",m_PropertyInfoMap["PtsArray[0]"].propertyValue.toPointF()},
        {"PtsArray[1]",m_PropertyInfoMap["PtsArray[1]"].propertyValue.toPointF()},
        {"PtsArray[2]",m_PropertyInfoMap["PtsArray[2]"].propertyValue.toPointF()}
    };
    updateDraw();
    this->setPen(QColor(Qt::green));
    this->setEditPointF(editPoints);
}

GY_GraphicsPolyline::GY_GraphicsPolyline(const QString &guid,
                                         const QVector<QPointF> &PtsArray,
                                         const int Capacity,
                                         const int Size,
                                         QGraphicsItem *parent)
    :GY_BasicsGraphicsObject(guid,this,parent)
{
    //图元类型
    GY_Object::setUserData(GY_ENUM::ClassType,QVariant("PolylineItem"));
    initializationPropertyInfo();

    if(PtsArray.size() < 3)//给的点小于初始点个数
    {
        for(int i = 0;i < PtsArray.size();i++)
        {
            m_PropertyInfoMap[QString("PtsArray[%1]").arg(i)].propertyValue = PtsArray[i];//取点
            this->setEditPointF(QString("PtsArray[%1]").arg(i),PtsArray[i]);//为新添加的点画点
        }
        int num = 3-PtsArray.size();//要删掉的点数
        for(int i = 0;i < num;i++)
        {
            m_PropertyInfoMap.remove(QString("PtsArray[%1]").arg(2-i));
        }
        m_PropertyInfoMap["PtsArray.Size"].propertyValue = PtsArray.size();
        m_PropertyInfoMap["PtsArray.Capacity"].propertyValue = PtsArray.size();
    }
    else if(PtsArray.size() > 3)//给的点大于初始点个数
    {
        int num = PtsArray.size()-3;//要增加的点数5-3=2
        //改值操作，更改初始的三个点的坐标(向vector中存入map)
        m_PropertyInfoMap["PtsArray[0]"].propertyValue = PtsArray[0];
        m_PropertyInfoMap["PtsArray[1]"].propertyValue = PtsArray[1];
        m_PropertyInfoMap["PtsArray[2]"].propertyValue = PtsArray[2];
        QMap<QVariant,QPointF> editPoints = {
            {"PtsArray[0]",m_PropertyInfoMap["PtsArray[0]"].propertyValue.toPointF()},
            {"PtsArray[1]",m_PropertyInfoMap["PtsArray[1]"].propertyValue.toPointF()},
            {"PtsArray[2]",m_PropertyInfoMap["PtsArray[2]"].propertyValue.toPointF()}
        };
        this->setEditPointF(editPoints);
        for(int i = 0;i < num;i++)
        {
            //插入操作，插入新点
            GY_PropertyInfo PtsArrayProperty;//
            PtsArrayProperty.propertyName = QString("PtsArray[%1]").arg(i+3);
            PtsArrayProperty.propertyValue = PtsArray[i+3];//数组取值
            PtsArrayProperty.updateType = MoveUpdate|PointOfRelative;
            PtsArrayProperty.propertyType = PointPropertyType;
            PtsArrayProperty.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsPolyline::updatePtsArray;
            m_PropertyInfoMap.insert(PtsArrayProperty.propertyName,PtsArrayProperty);
            m_PropertyInfoMap[PtsArrayProperty.propertyName].setConnect();//建立连接
            this->setEditPointF(PtsArrayProperty.propertyName,PtsArrayProperty.propertyValue.toPointF());
        }
        m_PropertyInfoMap["PtsArray.Size"].propertyValue = PtsArray.size();
        m_PropertyInfoMap["PtsArray.Capacity"].propertyValue = PtsArray.size();
    }
    else//给的点等于初始点个数
    {
        m_PropertyInfoMap["PtsArray[0]"].propertyValue = PtsArray[0];
        m_PropertyInfoMap["PtsArray[1]"].propertyValue = PtsArray[1];
        m_PropertyInfoMap["PtsArray[2]"].propertyValue = PtsArray[2];
        QMap<QVariant,QPointF> editPoints = {
            {"PtsArray[0]",m_PropertyInfoMap["PtsArray[0]"].propertyValue.toPointF()},
            {"PtsArray[1]",m_PropertyInfoMap["PtsArray[1]"].propertyValue.toPointF()},
            {"PtsArray[2]",m_PropertyInfoMap["PtsArray[2]"].propertyValue.toPointF()}
        };
        this->setEditPointF(editPoints);
    }

    updateDraw();
    this->setPen(QColor(Qt::green));
}

GY_GraphicsPolyline::~GY_GraphicsPolyline()
{

}

GY_Object *GY_GraphicsPolyline::copyItem(const QString &guid)
{
    if(getUserData(GY_ENUM::IsCopy) == 1) {
        GY_Object *tmp;
        this->copyItemSig(&tmp);
        //更新copyItem属性列表
        QMap<QString,GY_PropertyInfo>::Iterator iterProperty = m_PropertyInfoMap.begin();
        while (iterProperty != m_PropertyInfoMap.end()) {
            if(iterProperty.key() == "PtsArray.Capacity")
                tmp->updateProperty(iterProperty.key(), iterProperty.value().propertyValue);
            if(iterProperty.key() == "PtsArray.Size")
                tmp->updateProperty(iterProperty.key(), iterProperty.value().propertyValue);

            ++iterProperty;
        }
        iterProperty = m_PropertyInfoMap.begin();
        while (iterProperty != m_PropertyInfoMap.end()) {
            if(((iterProperty.value().updateType)&PointOfRelative) == PointOfRelative) {
                tmp->updateProperty(iterProperty.key(), submittingPropertyValues(iterProperty.value().updateType,iterProperty.value().propertyValue,this));
            }else if(((iterProperty.value().updateType)&NotUpdate) == NotUpdate){
                ++iterProperty;
                continue;
            }else {
                tmp->updateProperty(iterProperty.key(), iterProperty.value().propertyValue);
            }
            ++iterProperty;
        }
        return tmp;
    }
    GY_Object* pObj;
    if(guid.isEmpty()) {
        pObj = (GY_Object*)GY_GraphicsReflection::getInstance()->newInstanceObjectClass(this->metaObject()->className(),this->getGuid()+"-"+QString::number(m_MyGuid));
        m_MyGuid++;
    }else {
        pObj = (GY_Object*)GY_GraphicsReflection::getInstance()->newInstanceObjectClass(this->metaObject()->className(),guid);
    }
    if(pObj == nullptr) {
        qDebug()<<this->getGuid()<<"isEmpty";
        return nullptr;
    }
    QMap<QString,GY_PropertyInfo>::Iterator iter = m_PropertyInfoMap.begin();
    while (iter != m_PropertyInfoMap.end()) {
        if(iter.key() == "PtsArray.Capacity")
            pObj->updateProperty(iter.key(), iter.value().propertyValue);
        if(iter.key() == "PtsArray.Size")
            pObj->updateProperty(iter.key(), iter.value().propertyValue);

        ++iter;
    }
    iter = m_PropertyInfoMap.begin();
    while (iter != m_PropertyInfoMap.end()) {
        if(((iter.value().updateType)&PointOfRelative) == PointOfRelative) {
            pObj->updateProperty(iter.key(), submittingPropertyValues(iter.value().updateType,iter.value().propertyValue,this));
        }else if(((iter.value().updateType)&NotUpdate) == NotUpdate){
            ++iter;
            continue;
        }else {
            pObj->updateProperty(iter.key(), iter.value().propertyValue);
        }
//        qDebug()<<iter.value().propertyValue<<"============="<<iter.key()<<"------------------------------------";
        ++iter;
    }
    connect(pObj,&GY_Object::copyItemSig,this,&GY_Object::originalVersion);
    pObj->setUserData(GY_ENUM::IsCopy, QVariant::fromValue(1));
    return pObj;
}
/**
 * @brief GY_GraphicsPolyline::updateCapacity 更新点数容量
 * @param name
 * @param value
 * @return
 */
bool GY_GraphicsPolyline::updateCapacity(const QString &name, const QVariant &value)
{
    if(!value.canConvert<int>() || (value.toInt()<0 && value.toInt()>9999)){
        return false;
    }
    int size = m_PropertyInfoMap["PtsArray.Size"].propertyValue.toInt();
    m_PropertyInfoMap[name].propertyValue=value;
#if(0)
    struct AA
    {

        int x;
        int y;
    };
    AA a[2]={};
    a[0].x=100;
#endif
    if(value < size)
    {
        this->updateSize("PtsArray.Size",value);
    }

    return true;
}
/**
 * @brief GY_GraphicsPolyline::updateSize 更新点数
 * @param name
 * @param value
 * @return
 */
bool GY_GraphicsPolyline::updateSize(const QString &name, const QVariant &value)
{
    if(!value.canConvert<int>() || (value.toInt()<0 && value.toInt()>9999))
    {
        return false;
    }
    int size=value.toInt();//获取传入点数
//    qDebug()<<"size"<<size;
    //已有点数
    int sizeOld=m_PropertyInfoMap[name].propertyValue.toInt();
    //将存入的初始化节点信息从map中取出
    QMap<QVariant, QPointF> editPoint = getEditPointF();
    QString pointName;
    //传入点数多于已有点数
    if(size>sizeOld)
    {
        for(int index=sizeOld;index<size;index++)
        {
            GY_PropertyInfo PtsArray(this);//PtsArray[2]
            PtsArray.propertyName = QString("PtsArray[%1]").arg(index);
            PtsArray.propertyValue = QPointF(0,0);
            PtsArray.updateType = Update|MoveUpdate|PointOfRelative;
            PtsArray.propertyType = PointPropertyType;
            PtsArray.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsPolyline::updatePtsArray;
            m_PropertyInfoMap.insert(PtsArray.propertyName,PtsArray);
            m_PropertyInfoMap[PtsArray.propertyName].setConnect();
            this->setEditPointF(PtsArray.propertyName,PtsArray.propertyValue.toPointF());
        }
    }
    else if(size<sizeOld)
    {
        for(int index=size;index<sizeOld;index++)
        {
            pointName = QString("PtsArray[%1]").arg(index);
            m_PropertyInfoMap.remove(pointName);//删除点属性
            this->deleeteEditPointF(pointName);//删除红点

        }

    }
    m_PropertyInfoMap["PtsArray.Size"].propertyValue=size;
    updateDraw();
    return true;
}
/**
 * @brief GY_GraphicsPolyline::updatePtsArray 更新点坐标
 * @param name
 * @param value
 * @return
 */
bool GY_GraphicsPolyline::updatePtsArray(const QString &name, const QVariant &value)
{
    if(!value.canConvert<QPointF>()){
        return false;
    }
    //获取鼠标坐标
    QPointF mousePoint = this->mapFromScene(value.value<QPointF>());
    m_PropertyInfoMap[name].propertyValue=mousePoint;
    //赋予被选中的编辑点的坐标为鼠标坐标
    this->setEditPointF(name,mousePoint);
    updateDraw();
    return true;
}
/**
 * @brief GY_GraphicsPolyline::updateDraw 更新绘制
 */
void GY_GraphicsPolyline::updateDraw()
{
    int size = m_PropertyInfoMap["PtsArray.Size"].propertyValue.toInt();
    QString lineType = m_PropertyInfoMap["LineType"].propertyValue.toString();

    QPainterPath path;
    path.moveTo(m_PropertyInfoMap.value("PtsArray[0]").propertyValue.toPointF());

    if(lineType == "Line_Loop") {
        for(int i=1;i<size;i++)
        {
            path.lineTo(m_PropertyInfoMap.value(QString("PtsArray[%1]").arg(i)).propertyValue.toPointF());
        }
        path.closeSubpath();
    }else if(lineType == "Line_Segments") {
        for(int i=1;i<size;i++)
        {
            path.lineTo(m_PropertyInfoMap.value(QString("PtsArray[%1]").arg(i)).propertyValue.toPointF());
            i++;
            path.moveTo(m_PropertyInfoMap.value(QString("PtsArray[%1]").arg(i)).propertyValue.toPointF());
        }
    }else if(lineType == "Line_Strip") {
        for(int i=1;i<size;i++)
        {
            path.lineTo(m_PropertyInfoMap.value(QString("PtsArray[%1]").arg(i)).propertyValue.toPointF());
        }
    }else if(lineType == "Points") {
        //不连接线条,画圆
        for(int i=0;i<size;i++)
        {
            QBrush brush;
            QColor brushColor = m_PropertyInfoMap["PenColor"].propertyValue.value<QColor>();
            brush.setColor(brushColor);
            brush.setStyle(Qt::SolidPattern);
            this->setBrush(brush);
            qreal r = m_PropertyInfoMap["LineStyle"].propertyValue.value<LineStyle>().width;
            path.addEllipse(m_PropertyInfoMap.value(QString("PtsArray[%1]").arg(i)).propertyValue.toPointF().x() - r
                            ,m_PropertyInfoMap.value(QString("PtsArray[%1]").arg(i)).propertyValue.toPointF().y() - r,2*r,2*r);
        }
    }

    this->setPath(path);
}
/**
 * @brief GY_GraphicsPolyline::initializationPropertyInfo 初始化属性信息
 */
void GY_GraphicsPolyline::initializationPropertyInfo()
{
    GY_PropertyInfo ObjectName(this);
    ObjectName.propertyName = "ObjectName";
    ObjectName.propertyValue = QString();
    ObjectName.updateType = Update|OrdinaryAttributes;
    ObjectName.propertyType = QStringPropertyType;
    ObjectName.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsPolyline::updateObjectName;
    m_PropertyInfoMap.insert("ObjectName",ObjectName);
    m_PropertyInfoMap["ObjectName"].setConnect();

    GY_PropertyInfo IsVisible(this);
    IsVisible.propertyName = "IsVisible";
    IsVisible.propertyValue = true;
    IsVisible.updateType = Update|OrdinaryAttributes;
    IsVisible.propertyType = BoolPropertyType;
    IsVisible.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsPolyline::updateIsVisible;
    m_PropertyInfoMap.insert("IsVisible",IsVisible);
    m_PropertyInfoMap[IsVisible.propertyName].setConnect();

    GY_PropertyInfo IsAntialiased(this);
    IsAntialiased.propertyName = "IsAntialiased";
    IsAntialiased.propertyValue = true;
    IsAntialiased.updateType = Update|OrdinaryAttributes;
    IsAntialiased.propertyType = BoolPropertyType;
    IsAntialiased.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsPolyline::updateIsAntialiased;
    m_PropertyInfoMap.insert("IsAntialiased",IsAntialiased);
    m_PropertyInfoMap[IsAntialiased.propertyName].setConnect();

    GY_PropertyInfo PenAttributes(this);
    PenAttributes.propertyName = "PenAttributes";
    PenAttributes.propertyValue = false;
    PenAttributes.updateType = Update|OrdinaryAttributes;
    PenAttributes.propertyType = BoolPropertyType;
    PenAttributes.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsPolyline::updatePenAttributes;
    m_PropertyInfoMap.insert("PenAttributes",PenAttributes);
    m_PropertyInfoMap[PenAttributes.propertyName].setConnect();

    GY_PropertyInfo PenColor(this);
    PenColor.propertyName = "PenColor";
    PenColor.propertyValue = QColor();
    PenColor.updateType = Update|OrdinaryAttributes;
    PenColor.propertyType = ColorPropertyType;
    PenColor.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsPolyline::updatePenColor;
    m_PropertyInfoMap.insert("PenColor",PenColor);
    m_PropertyInfoMap[PenColor.propertyName].setConnect();

    GY_PropertyInfo LineStyle(this);
    LineStyle.propertyName = "LineStyle";
    QVector<qreal> lineStyle;
    int style = Qt::SquareCap|Qt::BevelJoin|Qt::CustomDashLine;
    lineStyle<<style<<2<<3<<4<<5<<6<<7;//自定义线条样式
    LineStyle.propertyValue = QVariant::fromValue(lineStyle);
    LineStyle.updateType = Update|OrdinaryAttributes;
    LineStyle.propertyType = LineStylePropertyType;
    LineStyle.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsPolyline::updateLineStyle;
    m_PropertyInfoMap.insert("LineStyle",LineStyle);
    m_PropertyInfoMap[LineStyle.propertyName].setConnect();
    //PtsArray
    GY_PropertyInfo Capacity(this);//Capacity
    Capacity.propertyName = "PtsArray.Capacity";
    Capacity.propertyValue = int(3);
    Capacity.updateType = Update|OrdinaryAttributes;
    Capacity.propertyType = IntPropertyType;
    Capacity.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsPolyline::updateCapacity;
    m_PropertyInfoMap.insert("PtsArray.Capacity",Capacity);
    m_PropertyInfoMap[Capacity.propertyName].setConnect();

    GY_PropertyInfo Size(this);//Size
    Size.propertyName = "PtsArray.Size";
    Size.propertyValue = int(3);
    Size.updateType = Update|OrdinaryAttributes;
    Size.propertyType = IntPropertyType;
    Size.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsPolyline::updateSize;
    m_PropertyInfoMap.insert("PtsArray.Size",Size);
    m_PropertyInfoMap[Size.propertyName].setConnect();

    GY_PropertyInfo PtsArray0(this);//PtsArray[0]
    PtsArray0.propertyName = "PtsArray[0]";
    PtsArray0.propertyValue = QPointF(0,0);
    PtsArray0.updateType = Update|MoveUpdate|PointOfRelative;
    PtsArray0.propertyType = PointPropertyType;
    PtsArray0.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsPolyline::updatePtsArray;
    m_PropertyInfoMap.insert("PtsArray[0]",PtsArray0);
    m_PropertyInfoMap[PtsArray0.propertyName].setConnect();

    GY_PropertyInfo PtsArray1(this);//PtsArray[1]
    PtsArray1.propertyName = "PtsArray[1]";
    PtsArray1.propertyValue = QPointF(100,200);
    PtsArray1.updateType = Update|MoveUpdate|PointOfRelative;
    PtsArray1.propertyType = PointPropertyType;
    PtsArray1.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsPolyline::updatePtsArray;
    m_PropertyInfoMap.insert("PtsArray[1]",PtsArray1);
    m_PropertyInfoMap[PtsArray1.propertyName].setConnect();

    GY_PropertyInfo PtsArray2(this);//PtsArray[2]
    PtsArray2.propertyName = "PtsArray[2]";
    PtsArray2.propertyValue = QPointF(300,300);
    PtsArray2.updateType = Update|MoveUpdate|PointOfRelative;
    PtsArray2.propertyType = PointPropertyType;
    PtsArray2.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsPolyline::updatePtsArray;
    m_PropertyInfoMap.insert("PtsArray[2]",PtsArray2);
    m_PropertyInfoMap[PtsArray2.propertyName].setConnect();

    GY_PropertyInfo AddPointAfter(this);//AddPointAfter
    AddPointAfter.propertyName = "AddPointAfter";
    AddPointAfter.propertyValue = int(-1);
    AddPointAfter.updateType = Update|OrdinaryAttributes;
    AddPointAfter.propertyType = IntPropertyType;
    AddPointAfter.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsPolyline::updateAddPointAfter;
    m_PropertyInfoMap.insert("AddPointAfter",AddPointAfter);
    m_PropertyInfoMap[AddPointAfter.propertyName].setConnect();

    GY_PropertyInfo AddPointBefore(this);//AddPointBefore
    AddPointBefore.propertyName = "AddPointBefore";
    AddPointBefore.propertyValue = int(-1);
    AddPointBefore.updateType = Update|OrdinaryAttributes;
    AddPointBefore.propertyType = IntPropertyType;
    AddPointBefore.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsPolyline::updateAddPointBefore;
    m_PropertyInfoMap.insert("AddPointBefore",AddPointBefore);
    m_PropertyInfoMap[AddPointBefore.propertyName].setConnect();

    GY_PropertyInfo RemovePoint(this);//RemovePoint
    RemovePoint.propertyName = "RemovePoint";
    RemovePoint.propertyValue = int(-1);
    RemovePoint.updateType = Update|OrdinaryAttributes;
    RemovePoint.propertyType = IntPropertyType;
    RemovePoint.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsPolyline::updateRemovePoint;
    m_PropertyInfoMap.insert("RemovePoint",RemovePoint);
    m_PropertyInfoMap[RemovePoint.propertyName].setConnect();

    GY_PropertyInfo LineType(this);//LineType
    LineType.propertyName = "LineType";
    LineType.propertyValue = QString("Line_Strip");
    LineType.updateType = Update|OrdinaryAttributes;
    LineType.propertyType = QStringPropertyType;
    LineType.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsPolyline::updateLineType;
    m_PropertyInfoMap.insert("LineType",LineType);
    m_PropertyInfoMap[LineType.propertyName].setConnect();
}

bool GY_GraphicsPolyline::updateAddPointAfter(const QString &, const QVariant &value)
{
    if(!value.canConvert<int>() || value < 0)
    {
        return false;
    }
    if(value.toInt() == -1) {
        return false;
    }
    int index=value.toInt();//选中点的索引
    int size=m_PropertyInfoMap.value("PtsArray.Size").propertyValue.toInt();//现有点数
    //考虑到调试时存在错误输入超出范围的数的可能
    if(index >= size-1)
    {
        index = size-1;
    }
    //更新点数size,每增加一次点数加一并存入
    m_PropertyInfoMap["PtsArray.Size"].propertyValue = ++size;
    for(int i = size-1;i > index;i--)
    {
        QString _name = QString("PtsArray[%1]").arg(i-1);
        GY_PropertyInfo propertyInfo(this);
        propertyInfo = m_PropertyInfoMap[_name];
        propertyInfo.propertyName = QString("PtsArray[%1]").arg(i);
        propertyInfo.propertyValue = int(i);
        propertyInfo.updateType = Update|OrdinaryAttributes;
        propertyInfo.propertyType = IntPropertyType;
        m_PropertyInfoMap[QString("PtsArray[%1]").arg(i)] = propertyInfo;
        m_PropertyInfoMap.insert(propertyInfo.propertyName,propertyInfo);
        m_PropertyInfoMap[propertyInfo.propertyName].setConnect();//建立连接
    }
    //新增节点为选中节点的后一个节点
    QString pointName=QString("PtsArray[%1]").arg(index+1);
    QPointF updatePoint=m_PropertyInfoMap[QString("PtsArray[%1]").arg(index+1)].propertyValue.toPointF();//新增节点(after)
    //若在尾节点后加点，则新增节点坐标为尾节点及首节点的坐标和的一半
    if(index == (size-1)-1)//尾节点name
    {
        //首节点
        QPointF startPoint = m_PropertyInfoMap["PtsArray[0]"].propertyValue.toPointF();
        //尾节点
        QPointF endPoint = m_PropertyInfoMap[QString("PtsArray[%1]").arg(size-1)].propertyValue.toPointF();
        //定义新增节点，取所选编辑点和该编辑点之后的点的中间坐标为新增节点
        updatePoint = QPointF((endPoint.x() + startPoint.x())/2,(endPoint.y() + startPoint.y())/2);
    }
    //若在非尾节点后加点，则新增节点坐标为该节点与其后一节点的坐标和的一半
    else if((index >= 0) && (index < (size-1)-1))//非尾节点name
    {
        //某非尾节点
        QPointF frontPoint = m_PropertyInfoMap[QString("PtsArray[%1]").arg(index)].propertyValue.toPointF();
        frontPoint = m_PropertyInfoMap.value(QString("PtsArray[%1]").arg(index)).propertyValue.value<QPointF>();
        //某非尾节点的后节点
        QPointF backPoint = m_PropertyInfoMap[QString("PtsArray[%1]").arg(index+2)].propertyValue.toPointF();
        backPoint = m_PropertyInfoMap.value(QString("PtsArray[%1]").arg(index+2)).propertyValue.value<QPointF>();
        //新增节点位置取在frontPoint和backPoint之间的中点
        updatePoint = QPointF(frontPoint.x()+(backPoint.x() - frontPoint.x())/2,frontPoint.y()+(backPoint.y() - frontPoint.y())/2);
    }
    //变换完成后为发生变换的点更新各类属性
    GY_PropertyInfo _propertyInfo(this);
    _propertyInfo = m_PropertyInfoMap[pointName];
    _propertyInfo.propertyName = pointName;
    _propertyInfo.propertyValue = index;
    _propertyInfo.updateType = Update|OrdinaryAttributes;
    _propertyInfo.propertyType = IntPropertyType;
    _propertyInfo.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsPolyline::updateAddPointAfter;
    m_PropertyInfoMap[pointName] = _propertyInfo;
    m_PropertyInfoMap.insert(_propertyInfo.propertyName,_propertyInfo);
    m_PropertyInfoMap[pointName].setConnect();

    //将存入的初始化节点信息从map中取出
    QMap<QVariant, QPointF> editPoint = getEditPointF();
    //更新编辑点
    for(int j=size-1;j > index;--j)
    {
        editPoint[QString("PtsArray[%1]").arg(j)] = editPoint[QString("PtsArray[%1]").arg(j-1)];
    }
    //添加新增节点
    setEditPointF(editPoint);
    this->setEditPointF(pointName,updatePoint);
    //存入新增节点
    m_PropertyInfoMap.insert(QString("PtsArray[%1]").arg(size+1),m_PropertyInfoMap[QString("PtsArray[%1]").arg(size+1)]);

    updateDraw();
    return true;
}

bool GY_GraphicsPolyline::updateAddPointBefore(const QString &, const QVariant &value)
{
    if(!value.canConvert<int>() || value < 0)
    {
        return false;
    }
    if(value.toInt() == -1) {
        return false;
    }
    int index=value.toInt();//选中点的索引
    int size=m_PropertyInfoMap["PtsArray.Size"].propertyValue.toInt();//现有点数
    //考虑到调试时存在错误输入超出范围的数的可能
    if(index >= size-1)
    {
        index = size-1;
    }
    //更新size，每增加一个点size+1
    m_PropertyInfoMap["PtsArray.Size"].propertyValue = ++size;
    for(int i = size-1;i > index;i--)//以当前节点数遍历节点;从选中节点的前一节点开始;从尾节点到选中节点开始遍历
    {//为下标发生变化的节点的各类属性进行初始化
        QString _name = QString("PtsArray[%1]").arg(i-1);
        GY_PropertyInfo propertyInfo(this);
        propertyInfo = m_PropertyInfoMap[_name];
        propertyInfo.propertyName = QString("PtsArray[%1]").arg(i);
        propertyInfo.propertyValue = int(i);
        propertyInfo.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsPolyline::updateAddPointBefore;
        m_PropertyInfoMap[QString("PtsArray[%1]").arg(i)] = propertyInfo;
        m_PropertyInfoMap[QString("PtsArray[%1]").arg(i)].setConnect();//建立连接
    }
    //新增节点为选中节点的前一个节点
    QString pointName=QString("PtsArray[%1]").arg(index);//新增节点的索引
    QPointF updatePoint;//定义新增节点，但需要考虑新增节点成为首节点的特殊情况
    //若在首节点前加节点，则新增节点坐标为尾节点及首节点的坐标和的一半
    if(index == 0)//首节点name（特殊情况）
    {
        updatePoint=m_PropertyInfoMap[pointName].propertyValue.toPointF();//新增节点(before)
        //首节点
        QPointF startPoint = m_PropertyInfoMap["PtsArray[0]"].propertyValue.toPointF();
        //尾节点
        QPointF endPoint = m_PropertyInfoMap[QString("PtsArray[%1]").arg(size-1)].propertyValue.toPointF();
        //新增节点位置取在startPoint和endPoint之间的中点
        updatePoint = QPointF((endPoint.x() + startPoint.x())/2,(endPoint.y() + startPoint.y())/2);
        //新增节点为首节点，原首节点及其之后的每个节点的标签以及位置都将后移一位
        GY_PropertyInfo _propertyInfo(this);
        _propertyInfo = m_PropertyInfoMap[pointName];
        _propertyInfo.propertyName = pointName;
        _propertyInfo.propertyValue = index;
        _propertyInfo.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsPolyline::updateAddPointBefore;
        m_PropertyInfoMap[pointName] = _propertyInfo;
        m_PropertyInfoMap.insert(_propertyInfo.propertyName,_propertyInfo);
        m_PropertyInfoMap[pointName].setConnect();

        //将存入的初始化节点信息从map中取出
        QMap<QVariant, QPointF> editPoint = getEditPointF();
        //更新编辑点（从新节点开始）
        for(int j=size-1;j > index-1;--j)
        {
            editPoint[QString("PtsArray[%1]").arg(j)] = editPoint[QString("PtsArray[%1]").arg(j-1)];
        }
    }
    //若在非首节点前加节点，则新增节点坐标为该节点与其前一节点的坐标和的一半
    else if((index >= 0) && (index < size-1))//非首节点name（普通情况）
    {
        updatePoint=m_PropertyInfoMap[QString("PtsArray[%1]").arg(index-1)].propertyValue.toPointF();//新增节点(before)
        //新增节点的前节点
        QPointF frontPoint = m_PropertyInfoMap[QString("PtsArray[%1]").arg(index-1)].propertyValue.toPointF();        
        //新增节点的后节点
        QPointF backPoint = m_PropertyInfoMap[QString("PtsArray[%1]").arg(index+1)].propertyValue.toPointF();
        //新增节点位置取在frontPoint和backPoint之间的中点
        if(backPoint.y()==frontPoint.y())//如果前后两点纵坐标相同
        {
            updatePoint = QPointF((backPoint.x() + frontPoint.x())/2,backPoint.y());
        }
        else if(backPoint.x()==frontPoint.x())//如果前后两点横坐标相同
        {
            updatePoint = QPointF(backPoint.x(),(backPoint.y() + frontPoint.y())/2);
        }
        else if((backPoint.x()==frontPoint.x())&&(backPoint.y()==frontPoint.y()))//如果前后两点横纵坐标相同
        {
            updatePoint = QPointF(backPoint.x(),backPoint.y());
        }
        else//如果前后两点横纵坐标不相同
        {
            updatePoint = QPointF((backPoint.x() + frontPoint.x())/2,(backPoint.y() + frontPoint.y())/2);
        }
//        qDebug()<<"frontPoint ="<<frontPoint<<"backPoint ="<<backPoint<<"updatePoint ="<<updatePoint;
    }
    //变换完成后为发生变换的点更新各类属性（重新赋值）
    GY_PropertyInfo _propertyInfo(this);
    _propertyInfo = m_PropertyInfoMap[pointName];
    _propertyInfo.propertyName = pointName;
    _propertyInfo.propertyValue = index;//updatePoint
    _propertyInfo.updateType = Update|OrdinaryAttributes;
    _propertyInfo.propertyType = IntPropertyType;
    m_PropertyInfoMap[pointName] = _propertyInfo;
    m_PropertyInfoMap.insert(_propertyInfo.propertyName,_propertyInfo);
    m_PropertyInfoMap[pointName].setConnect();

    //将存入的初始化节点信息从map中取出
    QMap<QVariant, QPointF> editPoint = getEditPointF();
    //更新编辑点（从新节点开始）
    for(int j=size-1;j > index;j--)
    {
        editPoint[QString("PtsArray[%1]").arg(j)] = editPoint[QString("PtsArray[%1]").arg(j-1)];//前后两点交换索引
    }
    editPoint[pointName] = updatePoint;
    //添加新增节点
    setEditPointF(editPoint);
    this->setEditPointF(pointName,updatePoint);
    //存入新增节点
    m_PropertyInfoMap.insert(QString("PtsArray[%1]").arg(size+1),m_PropertyInfoMap[QString("PtsArray[%1]").arg(size+1)]);

    updateDraw();
    return true;
}

bool GY_GraphicsPolyline::updateRemovePoint(const QString &, const QVariant &value)
{
    if(!value.canConvert<int>() || value < 0)
    {
        return false;
    }
    if(value.toInt() == -1) {
        return false;
    }
    int index=value.toInt();
    int size=m_PropertyInfoMap.value("PtsArray.Size").propertyValue.toInt();
    if(index > size)
    {
        return false;
    }
    for(int i=index;i<size-1;i++)
    {
        QString pointName=QString("PtsArray[%1]").arg(i);//所选节点索引
        QPointF updatePoint=m_PropertyInfoMap[QString("PtsArray[%1]")
                .arg(i+1)].propertyValue.toPointF();
        m_PropertyInfoMap[pointName].propertyValue=updatePoint;
        this->setEditPointF(pointName,updatePoint);
    }
    //移除尾节点
    m_PropertyInfoMap.remove(QString("PtsArray[%1]").arg(size-1));
    this->deleeteEditPointF(QString("PtsArray[%1]").arg(size-1));
    //size-1
    m_PropertyInfoMap["PtsArray.Size"].propertyValue=--size;
    updateDraw();

//！问题：删除节点后，不仅节点消失，而且该节点前一节点会与后一节点直接相连,首节点不与尾节点相连
//    QMapIterator<QString,PropertyInfo> iterProMap(m_PropertyInfoMap);//map迭代器
//    int proIndex = 0;//初始化键的下标
//    while (iterProMap.hasNext())//依次往后循环
//    {
//        iterProMap.next();
//        //刷新下标
//        if(iterProMap.value().propertyName.contains("PtsArray["))
//        {
//            PropertyInfo propertyInfo = iterProMap.value();
//            m_PropertyInfoMap.remove(iterProMap.key());
//            m_PropertyInfoMap.insert(QString("PtsArray[%1]").arg(proIndex),iterProMap.value());
//            proIndex++;
//        }
//    }

//    //更新编辑点
//    this->deleeteEditPointF(QString("PtsArray[%1]").arg(value.toInt()));
//    QMapIterator<QVariant, QPointF> itermap(this->getEditPointF());

//    QMap<QVariant, QPointF> newPointF;
//    int index = 0;
//    while(itermap.hasNext()){
//        itermap.next();
//        newPointF.insert(QString("PtsArray[%1]").arg(index),itermap.value());
//        index++;
//        qDebug()<<QString("PtsArray[%1]").arg(index);//!测试：遍历现有的点
//    }
//    this->setEditPointF(newPointF);

//    QMapIterator<QString,PropertyInfo> iter(m_PropertyInfoMap);
//    while(iter.hasNext()){
//        iter.next();
//        QPointF pf = iter.value().propertyValue.toPointF();
//        if(pf == value.toPointF()){
//            m_PropertyInfoMap.remove(iter.key());
//            break;
//        }
//    }
//    int sizeOld=m_PropertyInfoMap["PtsArray.Size"].propertyValue.toInt();//已有点数
//    for(int index = 0; index < sizeOld; index++)
//    {
//        //若删除尾节点则其他节点不发生任何变化
//        if(name.endsWith(QString("PtsArray[%1]").arg(sizeOld)))
//        {
//            sizeOld -= 1;
//            sizeOld=m_PropertyInfoMap.value("PtsArray.Size").propertyValue.value<int>();
//            //删除尾节点
//            this->deleeteEditPointF(m_PropertyInfoMap[QString("PtsArray[%1]").arg(sizeOld)].propertyValue);
//        }
//        //若删除非尾节点,则其后一个节点将与其前一个节点相连，且其后若干节点的下标将-1
//        else if(name.endsWith(QString("PtsArray[%1]").arg(sizeOld-index)))
//        {
//            QPointF backPoint = m_PropertyInfoMap[QString("PtsArray[%1]").arg(sizeOld-index)].propertyValue.toPointF();
//            backPoint = m_PropertyInfoMap[QString("PtsArray[%1]").arg(sizeOld)].propertyValue.value<QPointF>();
//            //删除非尾节点
//            this->deleeteEditPointF(m_PropertyInfoMap[QString("PtsArray[%1]").arg(sizeOld-1)].propertyValue);
//        }
//    }
    return true;
}

bool GY_GraphicsPolyline::updateLineType(const QString &name, const QVariant &value)
{
    if(!value.canConvert<QString>())
    {
        return false;
    }
    m_PropertyInfoMap[name].propertyValue=value;
    updateDraw();
    return true;
}
